package se.kth.ik2200.carenet_2012;

import javax.bluetooth.RemoteDevice;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;

/**
 * Created with IntelliJ IDEA.
 * User: Ruslan Mukhammadov
 * Date: November 14, 2012
 * Time: 10:44 PM
 * To change this template use File | Settings | File Templates.
 */
public abstract class Device {

    /**
     * Returns the name of the given device
     *
     * @param remoteDevice - a device needed to obtain its name
     * @return - returns name string of given device
     * @throws java.io.IOException
     */
    protected static String extractDeviceName(RemoteDevice remoteDevice) throws IOException {
        String name = remoteDevice.getFriendlyName(false);
        String deviceName = name;
        if (name == null || name.equals("")) {
            deviceName = "Unknown";
        }

        return deviceName;
    }

    public abstract String getDeviceDescription();

    public abstract String getDeviceModel();

    public abstract String getDeviceName() throws IOException;

    public abstract String getDevicePinCode();

    public abstract RemoteDevice getInstance();

    /**
     * Connects to the selected device through a service,
     * opens an input stream and starts reading data.
     *
     * @param service - connection URL, we can call it serverURL
     * @param userName - login credential of the user to upload data to web-server
     * @throws InterruptedException
     * @throws java.io.IOException
     */
    public abstract void readDevice(String service, String userName)
            throws InterruptedException, IOException, NoSuchAlgorithmException, KeyManagementException;

    public abstract void setInstance(RemoteDevice remoteDevice);

    /**
     * Converts Input Stream into bytes.
     *
     * @param inputStream - input stream obtained from sensors
     * @return - returns bytes from provided input stream
     * @throws java.io.IOException
     */
    protected byte[] getBytesFromInputStream(InputStream inputStream) throws IOException {
        // Getting the size of the file in terms of bytes
        long length = inputStream.available();

        if (length > Integer.MAX_VALUE) {
            Log.printError("File is too large");
            return null;
        }

        // Creating the byte array to hold the data
        byte[] bytes = new byte[(int) length];

        // Reading in the bytes
        int offset = 0;
        int numRead;

        while (offset < bytes.length && (numRead = inputStream.read(bytes, offset, bytes.length - offset)) >= 0) {
            offset += numRead;
        }

        // Ensuring that all the bytes have been read in
        if (offset < bytes.length) {
            throw new IOException("Could not completely read the entire file.");
        }

        // Returning the processed result
        return bytes;
    }

    protected SensorData getDeviceData(String username) {
        SensorData data = new SensorData();
        data.setSensorModel(getDeviceModel());
        data.setSensorDescription(getDeviceDescription());
        data.setSensorPinCode(getDevicePinCode());
        data.setUsername(username);
        return data;
    }
}
